#include "vec2.h"
#include "dvec2.h"
#include "dvec3.h"
#include "dmat2.h"

namespace libvec
{
  dvec2::dvec2()
  {
    this->x = 0;
    this->y = 0;
  }

  dvec2::dvec2(vec2 v)
  {
    this->x = v.x;
    this->y = v.y;
  }

  dvec2::dvec2(dvec3 v)
  {
    this->x = v.x;
    this->y = v.y;
  }

  dvec2::dvec2(double value)
  {
    this->x = value;
    this->y = value;
  }

  dvec2::dvec2(double x, double y)
  {
    this->x = x;
    this->y = y;
  }

  double &dvec2::operator[](int index)
  {
    static double empty = 0;

    switch (index)
    {
      case 0:
        return this->x;

      case 1:
        return this->y;
    }

    return empty;
  }

  dvec2 dvec2::operator=(vec2 v)
  {
    this->x = v.x;
    this->y = v.y;

    return *this;
  }

  dvec2 dvec2::operator=(dvec2 v)
  {
    this->x = v.x;
    this->y = v.y;

    return *this;
  }

  dvec2 dvec2::operator=(dvec3 v)
  {
    this->x = v.x;
    this->y = v.y;

    return *this;
  }

  bool dvec2::operator==(dvec2 v)
  {
    return (this->x == v.x) && (this->y == v.y);
  }

  bool dvec2::operator!=(dvec2 v)
  {
    return (this->x != v.x) || (this->y != v.y);
  }

  dvec2 &dvec2::operator+()
  {
    return *this;
  }

  dvec2 &dvec2::operator-()
  {
    static dvec2 out;

    out.x = -this->x;
    out.y = -this->y;

    return out;
  }

  dvec2 dvec2::operator+(dvec2 v)
  {
    static dvec2 out;

    out.x = this->x + v.x;
    out.y = this->y + v.y;

    return out;
  }

  dvec2 dvec2::operator+=(dvec2 v)
  {
    this->x += v.x;
    this->y += v.y;

    return *this;
  }

  dvec2 dvec2::operator-(dvec2 v)
  {
    static dvec2 out;

    out.x = this->x - v.x;
    out.y = this->y - v.y;

    return out;
  }

  dvec2 dvec2::operator-=(dvec2 v)
  {
    this->x = this->x - v.x;
    this->y = this->y - v.y;

    return *this;
  }

  dvec2 dvec2::operator*(dmat2 m)
  {
    static dvec2 out;

    out.x = this->x*m.v1.x + this->y*m.v1.y;
    out.y = this->x*m.v2.x + this->y*m.v2.y;

    return out;
  }

  dvec2 dvec2::operator*=(dmat2 m)
  {
    this->x = this->x*m.v1.x + this->y*m.v1.y;
    this->y = this->x*m.v2.x + this->y*m.v2.y;

    return *this;
  }

  dvec2 dvec2::operator*(double scale)
  {
    static dvec2 out;

    out.x = this->x * scale;
    out.y = this->y * scale;

    return out;
  }

  dvec2 dvec2::operator*=(double scale)
  {
    this->x *= scale;
    this->y *= scale;

    return *this;
  }

  dvec2 dvec2::operator/(double scale)
  {
    static dvec2 out;

    out.x = this->x / scale;
    out.y = this->y / scale;

    return out;
  }

  dvec2 dvec2::operator/=(double scale)
  {
    this->x /= scale;
    this->y /= scale;

    return *this;
  }
}

